home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 1 Issue 2
/
PDCD-1 - Issue 02.iso
/
_utilities
/
utilities
/
003
/
motorola
/
Sources
/
c
/
util
< prev
Wrap
Text File
|
1993-07-18
|
14KB
|
551 lines
#include <setjmp.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "mselect.h" /*external selection of microprocessor symbol table*/
#include "proto.h"
#include "as.h"
#include "structs.h"
#include "riscos.h"
#include "extvars.h"
#define FATAL 2
#define SERIOUS 1
#define WARNING 0
#define MAXERR 100
/* Throwback routines Copyright ⌐ 1992 Niklas R÷jemo */
extern struct oper table[];
int pedantic = 1;
static int ThrowbackStarted;
static char *Filename;
static char errbuf[1024];
/*
* void errorInit(int throwback,char *np) { if(throwback) Filename =
* CanonicalisePath(np); else Filename = 0; }
*/
void
errorInit(int throwback, char *np)
{
if (throwback)
Filename = np;
else
Filename = 0;
#ifdef DEBUG
printf("filename = %s\n", np);
#endif
}
void
errorFinish(void)
{
if (ThrowbackStarted > 0) {
ThrowbackStarted = 0;
ThrowbackEnd();
}
}
static void
TB(int level, int lineno, char *error)
{
os_error *err;
if (!Filename)
return;
if (!ThrowbackStarted) {
err = ThrowbackStart();
if (err) {
fprintf(stderr, "ThrowbackStart %s\n", err->errmess);
exit(-1);
}
err = ThrowbackSendStart(Filename);
if (err) {
if (pedantic)
fprintf(stderr, "ThrowbackSendStart %s", err->errmess);
ThrowbackStarted = -1;
} else
ThrowbackStarted = 1;
}
if (ThrowbackStarted > 0)
ThrowbackSendError(level, lineno, error);
}
/*
* fatal --- fatal error handler
*/
void
fatal(char *str)
{
pouterror(FATAL, str); /* added ver TER_2.0 4 Jul 89 */
TB(FATAL, Local_Line_num, str);
#ifdef IBM /* changed ver TER_2.0 */
exit(-1);
#else
exit(10); /* Amiga & UNIX prefer positive numbers for
* error minimal error is 10 (no system prob) */
#endif
return; /* never executed */
}
/*
* error --- error in a line print line number and error
*/
void
error(char *str)
{
/*
* if(N_files > 1) commented out test for N_files in rel TER_2.0
* because a single command line source file (which is what N_file
* counts) can have multiple include source files.
*/
pouterror(SERIOUS, str);
TB(SERIOUS, Local_Line_num, str);
}
/*
* warn --- trivial error in a line print line number and error
*/
void
warn(char *str)
{
/*
* if(N_files > 1) commented out in rel TER_2.0 same reason as
* above
*/
pouterror(WARNING, str);
TB(WARNING, Local_Line_num, str);
}
/*
* delim --- check if character is a delimiter
*/
int
delim(char c)
{
if (any(c, " \t\n"))
return (YES);
return (NO);
}
/*
* skip_white --- move pointer to next non-whitespace char
*/
char *
skip_white(char *ptr)
{
while (*ptr == BLANK || *ptr == TAB)
ptr++;
return (ptr);
}
/*
* eword --- emit a word to code file
*/
void
eword(int wd)
{
emit(hibyte(wd));
emit(lobyte(wd));
}
/*
* emit --- emit a byte to code file
*/
int
emit(unsigned char byte)
{
#ifdef DEBUG
printf("%2x @ %4x\n", byte, Pc);
#endif
if (Pass == 1) {
Pc++;
return (YES);
}
if (P_total < P_LIMIT)
P_bytes[P_total++] = byte;
E_bytes[E_total++] = byte;
Pc++;
if (E_total == E_LIMIT)
f_record();
return;
}
/*
* f_record --- flush record out in `S1' format
*/
void
f_record(void)
{ /* made void for ANSI C compat ver TER_2.0
* 6/18/89 */
int i;
int chksum;
if (Pass == 1)
return;
if (E_total == 0) {
E_pc = Pc;
return;
}
F_total += E_total; /* total bytes in file ver (TER)2.01 19 Jun
* 89 */
chksum = E_total + 3; /* total bytes in this record */
chksum += lobyte(E_pc);
chksum += E_pc >> 8;
fprintf(Objfil, "S1"); /* record header preamble */
hexout(E_total + 3); /* byte count +3 */
hexout(E_pc >> 8); /* high byte of PC */
hexout(lobyte(E_pc)); /* low byte of PC */
for (i = 0; i < E_total; i++) {
chksum += lobyte(E_bytes[i]);
hexout(lobyte(E_bytes[i])); /* data byte */
}
chksum = ~chksum; /* one's complement */
hexout(lobyte(chksum)); /* checksum */
if (CRflag == 1) /* test for CRflag added ver TER_1.1 */
fprintf(Objfil, "%c\n", CR); /* print in IBM format for
* some PROM boxes */
else
fprintf(Objfil, "\n"); /* this is original statement */
E_pc = Pc;
E_total = 0;
}
char *hexstr = "0123456789ABCDEF";
void
hexout(int byte)
{
byte = lobyte(byte);
fprintf(Objfil, "%c%c", hexstr[byte >> 4], hexstr[byte & 017]);
return;
}
/*
* print_line --- pretty print input line
*/
void
print_line(void)
{
int i;
register char *ptr;
fprintf(Listfil, "%04d ", Line_num);
if (P_total || P_force)
{fprintf(Listfil,"%04x", Old_pc);}
else
{fprintf(Listfil," ");}
for (i = 0; i < P_total && i < 6; i++)
{fprintf(Listfil, " %02x", lobyte(P_bytes[i]));}
for (; i < 6; i++)
{fprintf(Listfil," ");}
fprintf(Listfil," ");
if (Cflag) {
if (Cycles)
{fprintf(Listfil, "[%2d ] ", Cycles);}
else
{fprintf(Listfil," ");}
}
ptr = Line;
while (*ptr != '\n') /* just echo the line back out */
{fputc(*ptr++,Listfil);}
for (; i < P_total; i++) {
if (i % 6 == 0)
{fprintf(Listfil,"\n ");};
fprintf(Listfil, " %02x", lobyte(P_bytes[i]));
}
if (Pflag50 && (++Page_lines >= PageLen)) /* form feed if flag set */
NewPage(); /* ver (TER) 2.02 19 Jun 89 */
fprintf(Listfil,"\n");
}
/*
* any --- does str contain c?
*/
int
any(char c, char *str)
{
while (*str != EOS)
if (*str++ == c)
return (YES);
return (NO);
}
/*
* mapdn --- convert A-Z to a-z
*/
char
mapdn(char c)
{
if (c >= 'A' && c <= 'Z')
return ((char) (c + 040)); /* cast value to char for
* ANSI C, ver TER_2.0 */
return (c);
}
/*
* lobyte --- return low byte of an int
*/
unsigned char
lobyte(int i)
{
return (i & 0xFF);
}
/*
* hibyte --- return high byte of an int
*/
unsigned char
hibyte(int i)
{
return ((i >> 8) & 0xFF);
}
/*
* head --- is str2 the head of str1?
*/
int
head(char *str1, char *str2)
{
while (*str1 != EOS && *str2 != EOS) {
if (*str1 != *str2)
break;
str1++;
str2++;
}
if (*str1 == *str2)
return (YES);
if (*str2 == EOS)
if (any(*str1, " \t\n,+-];*"))
return (YES);
return (NO);
}
/*
* alpha --- is character a legal letter
*/
int
alpha(char c)
{
if (c <= 'z' && c >= 'a')
return (YES);
if (c <= 'Z' && c >= 'A')
return (YES);
if (c == '_')
return (YES);
if (c == '.')
return (YES);
return (NO);
}
/*
* alphan --- is character a legal letter or digit
*/
int
alphan(char c)
{
if (alpha(c))
return (YES);
if (c <= '9' && c >= '0')
return (YES);
if (c == '$')
return (YES); /* allow imbedded $ */
if (c == '@')
return (YES); /* allow imbedded @, added ver TER_2.0 added
* to permit redefinable variables */
return (NO);
}
/*
* white --- is character whitespace?
*/
int
white(char c)
{
if (c == TAB || c == BLANK || c == '\n')
return (YES);
return (NO);
}
/*
* alloc --- allocate memory
*/
char *
alloc(int nbytes)
{
return (malloc(nbytes));
}
/*
* FNameGet --- Find a file name <file> or "file" in the Operand string added
* ver TER_2.0 6/17/89 note: this routine will return a file name with white
* space if between delimeters. This is permitted in AmigaDOS. Other DOS
* may hiccup or just use name up to white space
*/
int
FNameGet(char *NameString)
/* char *NameString; pointer to output string */
{
char *frompoint; /* pointers to input string, don't
* bash Operand */
char *topoint;/* pointer to output string, don't bash
* NameString */
frompoint = Operand; /* include file name is in parsed string
* Operand */
topoint = NameString; /* copy of pointer to increment in copying */
if (*frompoint != '<' && *frompoint != '"')
return (0); /* bad syntax */
frompoint++; /* skip < or " */
while (*frompoint != '>' && *frompoint != '"') { /* look for delimeter */
if (*frompoint == EOS)
return (0); /* missing delimeter */
*topoint++ = *frompoint++; /* copy path & file name for
* DOS */
}
*topoint = EOS; /* terminate file name */
#ifdef DEBUG2
printf("FNameGet: file name=%s\n", NameString);
#endif
return (1); /* proper syntax anyway */
}
/*
* --- strsave() find a place to save a string & return pointer to it added
* ver TER_2.0 6/18/89 function taken from Kernighan & Ritchie 78
*/
char *
strsave(char *s)
{
char *p;
if ((p = alloc(strlen(s) + 1)) != NULL)
strcpy(p, s);
return (p);
}
/*
* pouterror() ---- print out standard error header added rel TER_2.0 6/18/89
*/
void
pouterror(int err_type, char *str)
{
fprintf(stderr, "%s, line no. ", Argv[Cfn]); /* current file name */
fprintf(stderr, "%d: ", Local_Line_num); /* current line number */
fprintf(stderr, "%s\n", str);
/*
* NOTE: THERE IS NO \n ! Calling procedure supplies suffixing error
* message and \n. viz. file pseudo.c procedure do_pseudo in case
* INCLUDE. Note also that error count is incremented.
*/
Page_lines++; /* increment lines per page */
if (err_type != WARNING) {
Err_count++;
}
}
/*
* New Page() --- form feed a new page, print heading & inc page number Moved
* here from do_pseudo (pseudo.c) in ver (TER) 2.02 19 Jun 89 so that can
* call from print_line() as well for p50 option.
*/
void
NewPage(void)
{
Page_lines = 0; /* ver TER_2.08 so that OPT PAGE works */
fprintf(Listfil, "\n\f");
fprintf(Listfil, "%-10s", Argv[Cfn]);
fprintf(Listfil, " ");
fprintf(Listfil, "page %3d\n", Page_num++);
}
/*
* LastChar() ----- return a pointer to the last character in a string
* Exception: will return garbage if NULL string
*/
char *
LastChar(char *strpt)
/* strpt; pointer to string to be examined */
{
char *c;
c = strpt; /* don't zap original */
while (*c != EOS) /* search for end */
c++;
return (--c); /* back up one to last character */
}
#define OS_FSControl 0x29
#define DDEUtils_ThrowbackRegister 0x42585
#define DDEUtils_ThrowbackUnRegister 0x42586
#define DDEUtils_ThrowbackStart 0x42587
#define DDEUtils_ThrowbackSend 0x42588
#define DDEUtils_ThrowbackEnd 0x42580
#define Throwback_ReasonProcessing 0
#define Throwback_ReasonErrorDetails 1
#define Throwback_ReasonInfoDetails 2
os_error *
ThrowbackStart(void)
{
return os_swi0(os_X | DDEUtils_ThrowbackStart);
}
static char *ErrorFile;
os_error *
ThrowbackSendStart(char *filename)
{
ErrorFile = filename;
return os_swi3(os_X | DDEUtils_ThrowbackSend,
Throwback_ReasonProcessing, 0, (int) filename);
}
os_error *
ThrowbackSendError(int level, int lineno, char *error)
{
if (level == ThrowbackInfo)
return os_swi6(os_X | DDEUtils_ThrowbackSend,
Throwback_ReasonInfoDetails, 0, (int) ErrorFile,
lineno, 0, (int) error);
else
return os_swi6(os_X | DDEUtils_ThrowbackSend,
Throwback_ReasonErrorDetails, 0, (int) ErrorFile,
lineno, level, (int) error);
}
os_error *
ThrowbackEnd(void)
{
return os_swi0(os_X | DDEUtils_ThrowbackEnd);
}